package org.hackystat.projecttrajectory.db;

import java.util.logging.Logger;
import javax.xml.datatype.XMLGregorianCalendar;
import org.hackystat.projecttrajectory.resource.estimate.jaxb.ProjectEstimate;
import org.hackystat.projecttrajectory.server.Server;
import org.hackystat.sensorbase.resource.projects.jaxb.Project;
import org.hackystat.sensorbase.resource.users.jaxb.User;

/**
 * Provides a specification of the operations that must be implemented by every
 * ProjectTrajectory storage system. Also provides some 'helper' methods, which
 * return the Managers for the various resources.
 * 
 * @author Cam Moore
 */
public abstract class DbImplementation {

  /**
   * To be called as part of the startup process for a storage system. This
   * method should:
   * <ul>
   * <li> Check to see if this storage system has already been created during a
   * previous session.
   * <li> If no storage system exists, it should create one and initialize it
   * appropriately.
   * </ul>
   */
  public abstract void initialize();

  /**
   * Returns true if the initialize() method did indeed create a fresh storage
   * system. This is used by the ResourceManagers to determine if they should
   * read in default data or not.
   * 
   * @return True if the storage system is freshly created.
   */
  public abstract boolean isFreshlyCreated();

  /**
   * Returns the XML ProjectEstimateIndex for all Projects in this server.
   * 
   * @return The XML String containing an index to all project estimates.
   */
  public abstract String getProjectEstimateIndex();


  /**
   * Returns the EstimateIndex instance as XML string, or null if not found. The
   * EstimateIndex points to all the ProjectEstimates for the given project.
   * 
   * @param project The project.
   * @return The EstimateIndex XML string, or null.
   */
  public abstract String getProjectEstimateIndex(Project project);

  /**
   * Returns the XML ProjectEstimateIndex for the given project in this server.
   * 
   * @param projectName the project.
   * @return The XML String containing an index to the project's estimates.
   */
  public abstract String getProjectEstimateIndex(String projectName);

  /**
   * Returns the EstimateIndex for the given user. The EstimateIndex includes
   * all the estimates made by the user.
   * 
   * @param user the User who made the estimates.
   * @return The EstimateIndex as an XML String.
   */
  public abstract String getUserEstimateIndex(User user);

  /**
   * Returns the EstimateIndex for the given user. The EstimateIndex includes
   * all the estimates made by the user.
   * 
   * @param user the User who made the estimates.
   * @return The EstimateIndex as an XML String.
   */
  public abstract String getUserEstimateIndex(String user);

  /**
   * Returns true if the project has estimates.
   * 
   * @param project The project.
   * @return True if the given project has estimates.
   */
  public abstract boolean hasProjectEstimate(Project project);

  /**
   * Returns the user's ProjectEstimate for the given project. 
   * @param user the user.
   * @param project the project.
   * @return The XML String representation of the ProjectEstimate or null if none exist.
   */
  public abstract String getProjectEstimate(User user, Project project);
  
  /**
   * Returns the user's ProjectEstimate for the given project. 
   * @param user the user.
   * @param project the project.
   * @return The XML String representation of the ProjectEstimate or null if none exist.
   */
  public abstract String getProjectEstimate(String user, String project);
  
  /**
   * Returns true if the given project has an estimate with the given timestamp.
   * 
   * @param project The project.
   * @param timestamp The timestamp.
   * @return True if the project has an estimate with the timestamp.
   */
  public abstract boolean hasProjectEstimate(Project project, XMLGregorianCalendar timestamp);

  /**
   * Persists a ProjectEstimate instance. If ProjectEstimate with this [project,
   * timestamp] already exists in the storage system, it should be overwritten.
   * 
   * @return True if the project estimate was successfully inserted.
   * @param estimate The ProjectEstimate.
   * @param xmlProjectEstimate The ProjectEstimate marshalled into an XML
   *          String.
   * @param xmlEstimateRef The EstimateRef marshalled into an XML String.
   */
  public abstract boolean storeProjectEstimate(ProjectEstimate estimate, String xmlProjectEstimate,
      String xmlEstimateRef);

  /**
   * Ensures that the project estimate with the given project and timestamp is
   * no longer present in the db.
   * 
   * @param project The project.
   * @param timestamp The timestamp.
   */
  public abstract void deleteProjectEstimate(Project project, XMLGregorianCalendar timestamp);

  /**
   * Ensures that any project estimate with the given estimator and project name is
   * no longer in the db.
   * 
   * @param estimator the estimator.
   * @param projectName the name of the project.
   */
  public abstract void deleteProjectEstimate(String estimator, String projectName);
  
  /** allow access to the Server. */
  protected Server server;

  protected Logger logger;

  /**
   * Constructs a DbImplementation.
   * 
   * @param server The Server.
   */
  public DbImplementation(Server server) {
    this.server = server;
    this.logger = server.getLogger();
  }
}
